﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SwidHelperLib
{
    public partial class SwidHelper
    {
        private static string MICROSOFT_CORPORATION = "Microsoft Corporation";
        private static string MICROSOFT_REGID = "regid.1991-06.com.microsoft";

        private static string OUTERCURVE_FOUNDATION = "Outercurve Foundation";
        private static string OUTERCURVE_REGID = "regid.2008-09.org.wixtoolset";

        private static string SWIGTAD_FILE_EXTENSION = ".swidtag";
        private static string SWIDTAG_FILES_FOLDER = ".\\";

        private static char[] CHARS_TO_TRIM = { '{', '}' };

        public static void CreateSwidTagFileForProduct(            
            string regid, 
            string uniqueId, 
            string name, 
            Version version, 
            string manufacturer,
            IEnumerable<string> files)
        {
            string realRegid = regid;
            if ( String.IsNullOrEmpty( regid ) )
            {
                realRegid = SwidHelper.GetRegid( manufacturer );
            }

            string swidTagFilePrefix = "";
            if ( !( String.IsNullOrEmpty( realRegid ) ) )
            {
                StringBuilder sb = new StringBuilder( realRegid.Length + 2 );
                sb.Append( realRegid );
                sb.Append( ' ' );
                swidTagFilePrefix = sb.ToString();
            }

            //
            // Create the appropriate ProgramData subdirectory, if it doesn't
            // already exist
            //

            // TODO

            //
            // Create the appropriate filename for the new SWID tag file
            //
            StringBuilder swidTagFilename = new StringBuilder( Path.Combine( SwidHelper.SWIDTAG_FILES_FOLDER, swidTagFilePrefix ) );
            swidTagFilename.Append( name.Trim() );
            swidTagFilename.Append( SwidHelper.SWIGTAD_FILE_EXTENSION );

            //
            // Open the new SWID tag file stream for writing
            //
            string swidTag = SwidHelper.GetSwidTagStringForProduct( regid, uniqueId, name, version, manufacturer, files );
            File.WriteAllText( swidTagFilename.ToString(), swidTag );
        }

        public static string GetSwidTagStringForProduct(
            string regid,
            string uniqueId,
            string name,
            Version version,
            string manufacturer,
            IEnumerable<string> files = null )
        {
            string realRegid = regid;
            if ( String.IsNullOrEmpty( regid ) )
            {
                realRegid = SwidHelper.GetRegid( manufacturer );
            }

            //
            // Open the new SWID tag memory stream for writing
            //
            using ( MemoryStream ms = new MemoryStream() )
            {
                //
                // Use the CreateTagFile helper in this assembly to write the tag
                // data to the file
                //

                CreateTagFile(
                    ms,
                    realRegid,
                    uniqueId.Trim( SwidHelper.CHARS_TO_TRIM ),
                    name,
                    version,
                    manufacturer,
                    false,
                    TagType.Application,
                    files,
                    null );

                return Encoding.UTF8.GetString( ms.ToArray() );
            }
        }

        private static string GetRegid( string companyName )
        {
            if ( companyName.Equals( SwidHelper.MICROSOFT_CORPORATION, StringComparison.OrdinalIgnoreCase ) )
            {
                return SwidHelper.MICROSOFT_REGID;
            }

            if ( companyName.Equals( SwidHelper.OUTERCURVE_FOUNDATION, StringComparison.OrdinalIgnoreCase ) )
            {
                return SwidHelper.OUTERCURVE_REGID;
            }

            return "";
        }
    }
}
